#include "global_macros.h"
#include "btreenode.h"


extern BTREE_NODE *btreenode_new(char data)
{
    BTREE_NODE *new_node = (BTREE_NODE *) malloc(sizeof (BTREE_NODE));
    ENSURE_ENOUGH_MEMORY(new_node, "btreenode_new");
    new_node->value = data;
    new_node->left_child = NULL;
    new_node->right_child = NULL;
    
    return new_node;
}

extern BTREE_NODE *btreenode_clone(BTREE_NODE *node)
{
    BTREE_NODE *cloned_node;

    if (node)
    {
        cloned_node = btreenode_new(node->value);
        cloned_node->left_child = btreenode_clone(node->left_child);
        cloned_node->right_child = btreenode_clone(node->right_child);
    }
    else
    {
        cloned_node = NULL;
    }

    return cloned_node;
}

extern char btreenode_get_data(BTREE_NODE *node)
{
    return (node) ? node->value : '\0';
}

extern BTREE_NODE *btreenode_get_left(BTREE_NODE *node)
{
    return (node) ? node->left_child : node;
}

extern BTREE_NODE *btreenode_get_right(BTREE_NODE *node)
{
    return (node) ? node->right_child : node;
}

extern BOOL btreenode_is_leaf(BTREE_NODE *node)
{
    return node->left_child == NULL && node->right_child == NULL;
}

extern BOOL btreenode_set_left(BTREE_NODE *parent_node, BTREE_NODE *node)
{
    BOOL set = FALSE;

    if (parent_node->left_child == NULL)
    {
        parent_node->left_child = node;
        set = TRUE;
    }

    return set;
}

extern BOOL btreenode_set_right(BTREE_NODE *parent_node, BTREE_NODE *node)
{
    BOOL set = FALSE;

    if (parent_node->right_child == NULL)
    {
        parent_node->right_child = node;
        set = TRUE;
    }

    return set;
}

extern void btreenode_set_data(BTREE_NODE *node, char data) {
    if (!node) {
        return;
    }
    node->value = data;
}

extern BOOL btreenode_equals(BTREE_NODE *node1, BTREE_NODE *node2)
{
    BOOL is_equal;
    if (node1 == NULL || node2 == NULL)
    {
        if (node1 == NULL && node2 == NULL)
        {
           is_equal = TRUE;
        }
    }
    else
    {
        is_equal = node1->value == node2->value
                && btreenode_equals(node1->left_child, node2->left_child)
                && btreenode_equals(node1->right_child, node2->right_child);
    }
    return is_equal;
}

extern void btreenode_print(BTREE_NODE *node, PRINT_FCT print_data)
{
    printf("|-- (0x%x:", node);
}

